<template>
  <div class="content-top-wrap">
    <Button v-show="showEditBtn" class="dib mr10" type="primary" size="small" @click="handleHasEdit">编辑</Button>
    <span v-show="hasEdited">
      <Upload class="dib mr10" action="/" :before-upload="handleBeforeUploda">
        <Button type="info" icon="ios-cloud-upload-outline" size="small">上传图片</Button>
      </Upload>
      <span v-show="showBtns">
        <Button v-show="showMd" class="dib mr10" type="primary" size="small" @click="handleMdClick">描点</Button>
        <span v-show="showMdOk">
          <Button class="dib mr10" type="success" size="small" @click="handleMdDone">{{ showBtnText }}</Button>
          <Button class="dib" type="warning" size="small" @click="handleSetCancel">回退</Button>
        </span>
        <span v-show="showEdit_1">
          <Button v-show="showOtherBtns" class="dib mr10" type="primary" size="small" @click="handleLxClick"
            >连线</Button
          >
          <Button v-show="showOtherBtns" class="dib mr10" type="primary" size="small" @click="handleSetPoint"
            >设置点</Button
          >
          <Button v-show="showOtherBtns" class="dib mr10" type="primary" size="small" @click="handleSetLine"
            >设置管道</Button
          >
          <Button v-show="showOtherBtns" class="dib mr10" type="primary" size="small" @click="handleFwdClick"
            >设置范围点</Button
          >
          <Button v-show="showOtherBtns" class="dib mr10" type="primary" size="small" @click="handleLxwtClick"
            >连线微调</Button
          >
          <span v-show="showEdit_2">
            <Button class="dib mr10" type="success" size="small" @click="handleSetOver">{{ showBtnText }}</Button>
            <span v-show="show3D">
              <Button class="dib mr10" type="info" size="small">TOP图</Button>
              <Button class="dib mr10" type="primary" size="small">3D图</Button>
            </span>
            <Button class="dib mr10" type="warning" size="small" @click="handleSetCancel">回退</Button>
          </span>
          <Tooltip v-show="showLxTip" transfer max-width="500">
            <Icon type="md-help-circle" class="tip-icon" />
            <div slot="content">
              <p>提示:</p>
              <p v-for="(text, index) of showTipText" :key="index">{{ text }}</p>
            </div>
          </Tooltip>
        </span>
        <Button v-show="showSaveBtn" class="dib mr10" type="success" size="small" @click="handleSave" :loading="saveLoading">保存</Button>
      </span>
    </span>
  </div>
</template>

<script>
import { each, keys, includes, cloneDeep } from 'lodash'
import { createNamespacedHelpers } from 'vuex'
const { mapActions, mapState } = createNamespacedHelpers('modeling')

const okBtnText = {
  md: '完成描点',
  lx: '完成连线',
  szd: '完成设置点',
  szgd: '完成设置管道',
  fwd: '完成点选取,并投影到地图',
  lxwt: '完成连线微调'
}

const tipText = {
  lx: ['1、选取至少2个点后敲击 键盘回车键 即可进行连线操作']
}

const pointValidateField = ['dotNumber', 'x', 'y']
const lxValidateField = [
  'pipeNumber',
  'startX',
  'startY',
  'endX',
  'endY',
  'diameter',
  'pipeLength',
  'temperature',
  'roughness',
  'texture',
  'lamdaOption',
  're',
  'startDotNumber',
  'endDotNumber'
]

export default {
  name: 'Modeling',
  data() {
    return {
      saveLoading: false
    }
  },
  computed: {
    ...mapState([
      'imgUrl',
      'hasMd',
      'hasLx',
      'toolType',
      'mdList',
      'rangePoint',
      'okRangePoint',
      'lxList',
      'hasLxEdit',
      'windowW',
      'windowH',
      'hasEdited',
      'hasShowEditBtn'
    ]),
    showEditBtn() {
      return !this.hasEdited && this.hasShowEditBtn
    },
    showBtnText() {
      return okBtnText[this.toolType] || '完成设置'
    },
    showBtns() {
      return !!this.imgUrl
    },
    showMd() {
      return !this.hasMd && !this.toolType
    },
    showMdOk() {
      return this.hasMd && this.toolType === 'md'
    },
    showOtherBtns() {
      return !this.toolType
    },
    showEdit_1() {
      return this.mdList.length > 0
    },
    showEdit_2() {
      return this.toolType && !['md'].includes(this.toolType)
    },
    showLxTip() {
      return this.toolType === 'lx'
    },
    showTipText() {
      return tipText[this.toolType]
    },
    show3D() {
      return this.toolType === 'fwd'
    },
    showSaveBtn() {
      return this.showMd && this.mdList.length > 0 && this.lxList.length > 0
    }
  },
  created() {
    this.getParams()
  },
  methods: {
    ...mapActions([
      'uploadImg',
      'changeHasMd',
      'changeHasLx',
      'changeToolType',
      'changeMdList',
      'changeLxList',
      'changeImgUrl',
      'changeShowRangePoint',
      'changeOkRangePoint',
      'changeHasLxEdit',
      'loadSaveData',
      'loadParams',
      'changeWindowW',
      'changeWindowH',
      'changeHasEdited',
      'changeHasEditBtn',
      'changeRangePoint'
    ]),
    handleHasEdit() {
      this.$emit('edit')
      this.changeHasEdited(true)
      this.$nextTick(() => {
        const oldMdList = cloneDeep(this.mdList)
        const oldLxList = cloneDeep(this.lxList)
        this.changeMdList(oldMdList)
        this.changeLxList(oldLxList)
      })
    },
    async getParams() {
      this.changeHasEditBtn(false)
      const { code, date } = await this.loadParams()
      if (code === 200) {
        this.changeHasEditBtn(true)
        const { img, width, height, dotList, pipelineList } = date
        const mdList = this.modifyList(dotList)
        const lxList = this.modifyList(pipelineList)
        this.changeWindowW(width)
        this.changeWindowH(height)

        this.$nextTick(() => {
          this.changeImgUrl(img)
          this.changeMdList(mdList)
          this.changeLxList(lxList)
        })
      }
    },
    modifyList(list) {
      const newList = []
      each(list, item => {
        const { operation, ...rest } = item
        let obj = {}
        try {
          const { rangePoint, ...other } = JSON.parse(operation)
          obj = other
          if (rangePoint && Array.isArray(rangePoint)) {
            this.changeRangePoint(rangePoint)
          }
        } catch (error) {
          //
        }
        newList.push(Object.assign({}, rest, obj))
      })

      return newList
    },
    handleBeforeUploda(file) {
      const imgFormats = ['image/jpg', 'image/jpeg', 'image/png']
      if (imgFormats.includes(file.type)) {
        this.uploadImg(file)
      } else {
        this.$Notice.warning({
          title: '操作提示',
          desc: '图片格式不支持'
        })
      }
      return false
    },
    handleMdClick() {
      this.changeHasMd(true)
      this.changeToolType('md')
    },
    handleMdDone() {
      this.changeHasMd(false)
      this.changeToolType(undefined)
    },
    handleMdCancel() {
      this.changeHasMd(false)
      this.changeMdList([])
      this.changeToolType(undefined)
    },
    handleLxClick() {
      if (this.mdList.length < 1) {
        return this.$Notice.warning({
          title: '操作提示',
          desc: '没有可操作的数据'
        })
      }
      this.changeHasLx(true)
      this.changeToolType('lx')
    },
    handleLxDone() {
      this.changeHasLx(false)
      this.changeToolType(undefined)
    },
    handleLxCancel() {
      this.changeHasLx(false)
    },
    handleFwdClick() {
      this.changeToolType('fwd')
      this.changeOkRangePoint(false)
    },
    handleFwdDone() {
      this.changeOkRangePoint(true)
      this.$nextTick(() => {
        const len = this.rangePoint.length
        if (len !== 2) {
          return this.$Notice.warning({
            title: '操作提示',
            desc: '请选择2个范围点'
          })
        }
        this.changeHasEdited(false)
        this.changeShowRangePoint(false)
        this.changeToolType(undefined)
      })
    },
    handleFwdCancel() {
      this.changeShowRangePoint(false)
      this.changeOkRangePoint(false)
      this.changeToolType(undefined)
    },
    handleLxwtClick() {
      this.changeHasLxEdit(true)
      this.changeToolType('lxwt')
    },
    handleLxwtDone() {
      this.changeToolType(undefined)
    },
    handleLxwtCancel() {
      this.changeHasLxEdit(false)
    },
    handleSetPoint() {
      this.changeToolType('szd')
    },
    handleSetLine() {
      const len = this.lxList.length
      if (len <= 0) {
        return this.$Notice.warning({
          title: '操作提示',
          desc: '没有可操作的数据'
        })
      }
      this.changeToolType('szgd')
    },
    handleSetOver() {
      switch (this.toolType) {
        case 'lx':
          this.handleLxDone()
          break
        case 'lxwt':
          this.handleLxwtDone()
          break
        case 'fwd':
          this.handleFwdDone()
          break
        default:
          this.changeToolType(undefined)
      }
    },
    handleSetCancel() {
      switch (this.toolType) {
        case 'md':
          this.handleMdCancel()
          break
        case 'fwd':
          this.handleFwdCancel()
          break
        case 'lx':
          this.handleLxCancel()
          break
        case 'lxwt':
          this.handleLxwtCancel()
          break
        default:
          break
      }
      this.changeToolType(undefined)
    },
    filterOtherKeys(data, hasList) {
      const keyList = keys(data)
      const otList = []
      each(keyList, key => {
        if (!includes(hasList, key)) {
          otList.push(key)
        }
      })

      return otList
    },
    modifySaveData() {
      const dotList = []
      const pipelineList = []
      each(this.mdList, item => {
        const { posi, ...rest } = item
        const otkeys = this.filterOtherKeys(item, pointValidateField)
        const operation = {}
        each(otkeys, key => {
          operation[key] = item[key]
        })
        operation.rangePoint = this.rangePoint
        dotList.push({
          ...rest,
          x: posi[0],
          y: posi[1],
          operation: JSON.stringify(operation)
        })
      })
      each(this.lxList, item => {
        const { linePoint, ...rest } = item
        const otkeys = this.filterOtherKeys(item, lxValidateField)
        const operation = {}
        each(otkeys, key => {
          operation[key] = item[key]
        })
        pipelineList.push({
          ...rest,
          startX: linePoint[0][0],
          startY: linePoint[0][1],
          endX: linePoint[1][0],
          endY: linePoint[1][1],
          operation: JSON.stringify(operation)
        })
      })

      return {
        dotList,
        pipelineList
      }
    },
    validateInfo(pList, xList) {
      const error = []
      let validated = true
      each(pList, item => {
        let flag = true
        for (let i = 0; i < pointValidateField.length; i++) {
          if (item[pointValidateField[i]] == null) {
            flag = false
            break
          }
        }
        if (!flag) {
          error.push(`编号 ${item.dotNumber} 的点设置信息不完整！`)
        }
      })
      each(xList, item => {
        let flag = true
        for (let i = 0; i < lxValidateField.length; i++) {
          if (item[lxValidateField[i]] == null) {
            flag = false
            break
          }
        }
        if (!flag) {
          error.push(`编号 ${item.pipeNumber} 的管道设置信息不完整！`)
        }
      })
      if (error.length > 0) {
        validated = false
      }
      return {
        validated,
        error
      }
    },
    async handleSave() {
      const { dotList, pipelineList } = this.modifySaveData()
      const { error } = this.validateInfo(dotList, pipelineList)
      if (!error.length) {
        const data = {
          img: this.imgUrl,
          width: this.windowW,
          height: this.windowH,
          dotList,
          pipelineList
        }
        this.saveLoading = true
        const { code, msg } = await this.loadSaveData(data)
        this.saveLoading = false
        if (code === 200) {
          this.$Message.success(msg)
        } else {
          this.$Message.warning(msg)
        }
      } else {
        this.$Message.warning({
          render: h => {
            const renderErrList = []
            each(error, err => {
              renderErrList.push(h('div', err))
            })
            return h('div', renderErrList)
          }
        })
      }
    }
  }
}
</script>

<style lang="less" scoped>
@deep: ~'>>>';
.content-top-wrap {
  width: 100%;
  height: 100%;
  overflow: hidden;
  margin-bottom: 10px;

  .dib {
    display: inline-block;
  }
  .mr10 {
    margin-right: 10px;
  }
  .tip-icon {
    color: #aaa;
    cursor: pointer;
  }
  @{deep} .ivu-upload-list {
    margin-top: 0;
  }
}
</style>
